/***********************************************
 This file is part of redia-bapps-main-ios.
 
 Copyright (c) 2015 Redia A/S
 
 Redia-bapps-main-ios is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 Redia-bapps-main-ios is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with redia-bapps-main-ios.  If not, see <http://www.gnu.org/licenses/>.
 
 *********************************************** */

//
//  BASearchResultsViewController.m
//  redia-bapps-ios
//
//  Created by Nikolaj Tørring on 8/9/13.
//  Copyright (c) 2013 redia. All rights reserved.
//

#import "BASearchResultsViewController.h"
#import "BASearchResultCell.h"
#import "BAMaterialViewController.h"
#import "BALoadingIndicatorCell.h"
#import "BACollection.h"
#import "BARPCManager.h"
#import "BAUserSearchViewController.h"
#import "BACoverUrl.h"
#import "InfoGalleriImageUrlUtils.h"
#import "BACoverUrlAndAvailabilityMemoryCache.h"
#import "BALibrarySettings.h"
#import "BARootViewController.h"
#import "BARelatedMaterialsListViewController.h"
#import "BAAddReservationViewController.h"
#import "BAPatronSettings.h"

#ifdef BA_LIBRARIAN_BUILD
#import "LBLibrarianMaterialViewController.h"
#import "LBLibrarianReservationViewController.h"
#endif

#ifdef BA_IMF_BUILD
#import "IMFPackageEditManager.h"
#endif

@interface BASearchResultsViewController () {
    //dep: NSMutableSet* currentImageLoaders;
    CGPoint oldOffset;
}

@property (nonatomic, strong) NSMutableArray* searchRecords;

@property (nonatomic, assign) BOOL isSearching;

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *filterButtonsHeight;

@property (nonatomic, assign) CGFloat initialScrollOffset;

@property (nonatomic, assign) BOOL isDragging;
@property (nonatomic, assign) BOOL isDecelerating;

@end


@implementation BASearchResultsViewController

-(void)commonInitBASearchResultsViewController
{
    //dep: currentImageLoaders=[NSMutableSet new];
}

- (id)init
{
    self = [super init];
    if (self) {
        [self commonInitBASearchResultsViewController];
    }
    return self;
}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        [self commonInitBASearchResultsViewController];
    }
    return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self commonInitBASearchResultsViewController];
    }
    return self;
}

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        [self commonInitBASearchResultsViewController];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    oldOffset = CGPointZero;
    //_rowHeights = [NSMutableDictionary new];
//    [self.tableView setContentInset:UIEdgeInsetsMake(98, 0, 0, 0)];
    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
 
    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
    
    [self.tableView setScrollsToTop:YES];
    
    if (RD_IS_IPAD) {
        [self.tableView registerNib:[UINib nibWithNibName:@"BASearchResultCell_iPad" bundle:nil] forCellReuseIdentifier:@"SearchResultCellNormal"];
        [self.tableView registerNib:[UINib nibWithNibName:@"BASearchResultCell_iPad" bundle:nil] forCellReuseIdentifier:@"SearchResultCellExpanded"];
    } else {
        [self.tableView registerNib:[UINib nibWithNibName:@"BASearchResultCell_iPhone" bundle:nil] forCellReuseIdentifier:@"SearchResultCellNormal"];
        [self.tableView registerNib:[UINib nibWithNibName:@"BASearchResultCell_iPhone" bundle:nil] forCellReuseIdentifier:@"SearchResultCellExpanded"];
    }

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableWithNotification:) name:BA_COVER_URL_CACHE_IMAGE_LOADED object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNewCoverUrls:) name:BA_COVER_URL_CACHE_COVER_URLS_ARRIVED object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableWithNotification:) name:BA_AVAILAIBILITY_CACHE_AVAILABILITIES_ARRIVED object:nil];

}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.tableView reloadData];
}

-(void)reloadTableWithNotification:(id)sender
{
    [self.tableView reloadData];
}

-(void)handleNewCoverUrls:(id)sender
{
    NSArray* visibleCells = [self.tableView visibleCells];
    NSMutableArray* visibleIdentifiers = [NSMutableArray new];
    
    for (BASearchResultCell* cell in visibleCells) {
        if ([cell isKindOfClass:[BASearchResultCell class]]) {
            if (cell.record && [cell.record.identifier length]>0) {
                [visibleIdentifiers addObject:cell.record.identifier];
            }
        }
    }
    [[BACoverUrlAndAvailabilityMemoryCache instance] fetchCoverImagesForIdentifiers:visibleIdentifiers];
}


- (void)dealloc
{
    [BARPCManager closeConnectionsForView:self];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BA_COVER_URL_CACHE_IMAGE_LOADED object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BA_COVER_URL_CACHE_COVER_URLS_ARRIVED object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:BA_AVAILAIBILITY_CACHE_AVAILABILITIES_ARRIVED object:nil];
    
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)appendSearchRecords:(NSArray*)records{
    if (_searchRecords == nil) {
        _searchRecords = [NSMutableArray new];
    }
    [_searchRecords addObjectsFromArray:records];
    [self.tableView reloadData];
    _isSearching = NO;
}

-(void)loadMoreResultsFailed
{
    _isSearching=NO;
}

-(void)appendAvailabilityRecords:(NSDictionary *)availabilities
{
    [[BACoverUrlAndAvailabilityMemoryCache instance] appendAvailabilityRecords:availabilities];
    
    [self.tableView reloadData];
}

-(void)appendCoverUrls:(NSDictionary *)coverUrls
{
    [[BACoverUrlAndAvailabilityMemoryCache instance] appendCoverUrls:coverUrls];
    
    [self.tableView reloadData];
}

-(void)clearSearchResults
{
    _searchRecords = nil;
    
    [self.tableView reloadData];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    if (self.searchRecords.count > 0) {
        if ([(BAUserSearchViewController*)self.baSearchViewController hasMoreResults]) {
            return 2;
        }
        else{
            return 1;
        }
    }
    return 0;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return self.searchRecords.count;
    } else{
        return 1;
    }
    
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        BOOL isExpanded = [self shouldCellBeExpandedForIndexPath:indexPath];
        BASearchResultCell* cell = nil;
        if (isExpanded) {
            cell = [tableView dequeueReusableCellWithIdentifier:@"SearchResultCellExpanded"];
        } else{
            cell = [tableView dequeueReusableCellWithIdentifier:@"SearchResultCellNormal"];
        }
//        NSDate* timespend = [NSDate date];


        cell.searchResultDelegate = self;

        cell.isShowingMoreView = isExpanded; //must be called before setRecord
        //DLog(@"idx %d expanded %d",indexPath.row,isExpanded);

        BARecord* record = [self.searchRecords objectAtIndex:indexPath.row];
        [cell setRecord:record];
        
        
        BACoverUrlAndAvailabilityMemoryCache* cache = [BACoverUrlAndAvailabilityMemoryCache instance];
        
        BAAvailability* availabilityInfo = [cache getAvailabilityForIdentifier:record.identifier];
        if (availabilityInfo) {
            [cell setAvailability:availabilityInfo];
        }
        
        [[BACoverUrlAndAvailabilityMemoryCache instance] fetchCoverImagesForIdentifiers:@[record.identifier]];
        
//        DLog(@"time: %lf",-[timespend timeIntervalSinceNow]);
        
        return cell;
    }
    else{
        BALoadingIndicatorCell* cell = [tableView dequeueReusableCellWithIdentifier:@"LoadingIndicatorCell"];
        if(cell == nil){
            cell = [[[NSBundle mainBundle] loadNibNamed:@"BALoadingIndicatorCell" owner:self options:nil] objectAtIndex:0];
        }
        
        [cell.loadingIndicator startAnimating];
        
        return cell;
    }
    
}

/*
-(void)printFrame:(UIView*)view
{
    DLog(@"frame: %@",NSStringFromCGRect(view.frame));
}
*/

-(BOOL)shouldCellBeExpandedForIndexPath:(NSIndexPath *)indexPath
{
    
    BARecord* record =  [self.searchRecords objectAtIndex:indexPath.row];
    BAPatronSettings* patronsettings = [BAPatronSettings instance];
    BOOL isExpanded = (record.moreInSameSeries && [patronsettings isUserAllowedLibrarianAccessForCurrentLibrary]) || [patronsettings isUserAllowedIMFEditorAccessForCurrentLibrary];
    
    return isExpanded;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.section == 1) {
        return 44;
    }
    
    BOOL isExpanded = [self shouldCellBeExpandedForIndexPath:indexPath];
    
    //DLog(@"idx %d expanded %d",indexPath.row,isExpanded);
    
    if (RD_IS_IPAD) {
        if (isExpanded) {
            return BA_SEARCH_RESULT_CELL_EXPANDED_HEIGHT_IPAD;
        } else {
            return BA_SEARCH_RESULT_CELL_DEFAULT_HEIGHT_IPAD;
        }
    } else {
        //iphone
        if (isExpanded) {
            return BA_SEARCH_RESULT_CELL_EXPANDED_HEIGHT_IPHONE;
        } else {
            return BA_SEARCH_RESULT_CELL_DEFAULT_HEIGHT_IPHONE;
        }
    }
    
}

-(BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView{
    if ([self.scrollViewDelegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)]) {
        return [self.scrollViewDelegate scrollViewShouldScrollToTop:scrollView];
    }
    return YES;
}

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    if ([self.scrollViewDelegate respondsToSelector:@selector(scrollViewWillBeginDragging:)]) {
        [self.scrollViewDelegate scrollViewWillBeginDragging:scrollView];
    }
    
    return;
    
    /* FIXME: old code?
    self.initialScrollOffset = scrollView.contentOffset.y;
    self.isDragging = YES;
    self.isDecelerating = NO;
     */
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if ([self.scrollViewDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) {
        [self.scrollViewDelegate scrollViewDidScroll:scrollView];
    }
    if (self.searchRecords.count == 0) {
        return;
    }
//    CGPoint newOffset = scrollView.contentOffset;
//    
//    if (self.baSearchViewController.isLargeFilterButtonsEnabled) {
//        if (oldOffset.y < newOffset.y && self.isDragging && self.baSearchViewController.isShowingLargeFilterButtons) {
//            [self.baSearchViewController hideFilterButtons:YES adjustOffset:NO animated:YES];
//        } else if (newOffset.y < -34 && !self.baSearchViewController.isShowingLargeFilterButtons){
//            if (self.isDragging) {
//                [self.baSearchViewController hideFilterButtons:NO adjustOffset:NO animated:YES];
//            }else{
//                [self.baSearchViewController hideFilterButtons:NO adjustOffset:YES animated:YES];
//            }
//        }
//    }
//    
//    
//    oldOffset = scrollView.contentOffset;
    
    CGFloat actualPosition = scrollView.contentOffset.y;
    CGFloat contentHeight = scrollView.contentSize.height-scrollView.frame.size.height;
    //CGFloat temp = scrollView.contentInset.top  ;
    //DLog(@"actualPosition: %f, initialScrollOffset: %f", actualPosition, temp);
    
    if (!_isSearching && actualPosition >= contentHeight && [(BAUserSearchViewController*)self.baSearchViewController hasMoreResults]) {
        _isSearching = YES;
        [(BAUserSearchViewController*)self.baSearchViewController loadMoreResults];
    }
}

-(void)scrollViewDidScrollToTop:(UIScrollView *)scrollView{
    if ([self.scrollViewDelegate respondsToSelector:@selector(scrollViewDidScrollToTop:)]) {
        [self.scrollViewDelegate scrollViewDidScrollToTop:scrollView];
    }
//    return;
//    [self.baSearchViewController hideFilterButtons:NO adjustOffset:YES animated:YES];

}


-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    if ([self.scrollViewDelegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)]) {
        [self.scrollViewDelegate scrollViewDidEndDecelerating:scrollView];
    }
    
    return;
    
//    self.isDecelerating = NO;
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    if ([self.scrollViewDelegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)]) {
        [self.scrollViewDelegate scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
    }
    
//    return;
//    
//    self.isDragging = NO;
//    if (decelerate) {
//        self.isDecelerating = YES;
//    }
//    
}

-(void)updateFilterMenuToScrollView:(UIScrollView*)scrollView{
    if (scrollView.contentOffset.y<-42) {
        return;
    }
    if (self.filterButtonsHeight.constant > 32) {
        [UIView animateWithDuration:0.1 delay:0 options:(UIViewAnimationOptionCurveLinear) animations:^{
            self.filterButtonsHeight.constant = 64;
            
            [self.baSearchViewController.view layoutIfNeeded];
        } completion:nil];
    } else if (self.filterButtonsHeight.constant <= 32 && self.filterButtonsHeight.constant > 0) {
        [UIView animateWithDuration:0.1 delay:0 options:(UIViewAnimationOptionCurveLinear) animations:^{
            self.filterButtonsHeight.constant = 0;
            [self.baSearchViewController.view layoutIfNeeded];
            
        } completion:nil];
    }
}

#pragma mark - Table view delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //open material view for record
    BARecord* rec = [self.searchRecords objectAtIndex:indexPath.row];
    BACoverUrlAndAvailabilityMemoryCache* cache = [BACoverUrlAndAvailabilityMemoryCache instance];
    BACoverUrl* cu_object = [cache getCoverUrlForIdentifier:rec.identifier];
    BAAvailability* availability = [cache getAvailabilityForIdentifier:rec.identifier];
    UIImage* currentImage = [cache getSearchResultCellSizedCoverImageForIdentifier:rec.identifier];

    UIViewController<BAMaterialViewControllerProtocol>* mvc = [[BARootViewController instance] createMaterialViewController];
    [self.navigationController pushViewController:mvc animated:YES];
    [mvc showRecord:rec withCoverUrl:cu_object.url currentImage:currentImage availability:availability];
}

#pragma mark - BASearchResultCellDelegate
-(void)searchResultCell:(BASearchResultCell *)cell seriesButtonClickedWithRecord:(BARecord *)record
{
    //FIXME: ipad??
    BARelatedMaterialsListViewController *vc = [[BARelatedMaterialsListViewController alloc] initWithNibName:@"BARelatedMaterialsListViewController" bundle:nil];
    vc.headerText = @"Mere i samme serie";
    [vc loadDataFromRecord:record withRelationType:BA_RELATED_MATERIAL_TYPE_MORE_IN_SERIES];

    [self.navigationController pushViewController:vc animated:YES];

}

-(void)searchResultCell:(BASearchResultCell *)cell clickedReserveButtonWithAvailability:(BAAvailability *)availability title:(NSString *)title
{
    if ([[BAPatronSettings instance] isUserAllowedLibrarianAccessForCurrentLibrary]) {
#ifdef BA_LIBRARIAN_BUILD
        LBLibrarianReservationViewController* lrvc = [LBLibrarianReservationViewController new];
        [lrvc setAvailability:availability andTitle:title];
        [self.navigationController pushViewController:lrvc animated:YES];
#endif
    } else {
       [BAAddReservationViewController createAddReservationDialogWithReservationId:availability.reservationId title:title];
    }
}


-(NSInteger)searchResultCount{
    return self.searchRecords.count;
}
@end
